
#include "stdafx.h"
#include "ADPCM.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
const short CADPCM::POWER2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000};
static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};

/// copy from CCITT G.711 specifications
const unsigned char CADPCM::_u2a[128] = // u- to A-law conversions
{
	1,	1,	2,	2,	3,	3,	4,	4,
		5,	5,	6,	6,	7,	7,	8,	8,
		9,	10,	11,	12,	13,	14,	15,	16,
		17,	18,	19,	20,	21,	22,	23,	24,
		25,	27,	29,	31,	33,	34,	35,	36,
		37,	38,	39,	40,	41,	42,	43,	44,
		46,	48,	49,	50,	51,	52,	53,	54,
		55,	56,	57,	58,	59,	60,	61,	62,
		64,	65,	66,	67,	68,	69,	70,	71,
		72,	73,	74,	75,	76,	77,	78,	79,
		81,	82,	83,	84,	85,	86,	87,	88,
		89,	90,	91,	92,	93,	94,	95,	96,
		97,	98,	99,	100,	101,	102,	103,	104,
		105,	106,	107,	108,	109,	110,	111,	112,
		113,	114,	115,	116,	117,	118,	119,	120,
		121,	122,	123,	124,	125,	126,	127,	128
};

const unsigned char CADPCM::_a2u[128] = // A- to u-law conversions
{
	1,	3,	5,	7,	9,	11,	13,	15,
		16,	17,	18,	19,	20,	21,	22,	23,
		24,	25,	26,	27,	28,	29,	30,	31,
		32,	32,	33,	33,	34,	34,	35,	35,
		36,	37,	38,	39,	40,	41,	42,	43,
		44,	45,	46,	47,	48,	48,	49,	49,
		50,	51,	52,	53,	54,	55,	56,	57,
		58,	59,	60,	61,	62,	63,	64,	64,
		65,	66,	67,	68,	69,	70,	71,	72,
		73,	74,	75,	76,	77,	78,	79,	79,
		80,	81,	82,	83,	84,	85,	86,	87,
		88,	89,	90,	91,	92,	93,	94,	95,
		96,	97,	98,	99,	100,	101,	102,	103,
		104,	105,	106,	107,	108,	109,	110,	111,
		112,	113,	114,	115,	116,	117,	118,	119,
		120,	121,	122,	123,	124,	125,	126,	127
};

CADPCM::CADPCM()
{
}

CADPCM::~CADPCM()
{
}

void CADPCM::g72x_state::Init()
{
	int		cnta;

	yl = 34816;
	yu = 544;
	dms = 0;
	dml = 0;
	ap = 0;
	for (cnta = 0; cnta < 2; cnta++)
	{
		a[cnta] = 0;
		pk[cnta] = 0;
		sr[cnta] = 32;
	}
	for (cnta = 0; cnta < 6; cnta++)
	{
		b[cnta] = 0;
		dq[cnta] = 32;
	}
	td = 0;
}

void CADPCM::Create(int coding_rule)
{
	_coding_rule = coding_rule;
	_state.Init();
}

// quantizes the input val against the table of size short integers.
// It returns i if table[i - 1] <= val < table[i].
// Using linear search for simple coding.
int CADPCM::quan(int val, short *table, int size)
{
	int i;

	for (i = 0; i < size; i++)
		if (val < *table++)
			break;
	return (i);
}

// returns the integer product of the 14-bit integer "an" and
// "floating point" representation (4-bit exponent, 6-bit mantessa) "srn".
int CADPCM::fmult(int an, int srn)
{
	short		anmag, anexp, anmant;
	short		wanexp, wanmant;
	short		retval;

	anmag = (an > 0) ? an : ((-an) & 0x1FFF);
	anexp = quan(anmag, (short*)POWER2, 15) - 6;
	anmant = (anmag == 0) ? 32 : (anexp >= 0) ? anmag >> anexp : anmag << -anexp;
	wanexp = anexp + ((srn >> 6) & 0xF) - 13;

	wanmant = (anmant * (srn & 077) + 0x30) >> 4;
	retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) : (wanmant >> -wanexp);

	return (((an ^ srn) < 0) ? -retval : retval);
}

// computes the estimated signal from 6-zero predictor.
int CADPCM::predictor_zero()
{
	//int		i;
	int		sezi;

	sezi = fmult(_state.b[0] >> 2, _state.dq[0]);
	//for (i = 1; i < 6; i++)			// ACCUM 
	//	sezi += fmult(_state.b[i] >> 2, _state.dq[i]);
	sezi += fmult(_state.b[1] >> 2, _state.dq[1]);
	sezi += fmult(_state.b[2] >> 2, _state.dq[2]);
	sezi += fmult(_state.b[3] >> 2, _state.dq[3]);
	sezi += fmult(_state.b[4] >> 2, _state.dq[4]);
	sezi += fmult(_state.b[5] >> 2, _state.dq[5]);
	return (sezi);
}

// computes the estimated signal from 2-pole predictor.
int CADPCM::predictor_pole()
{
	return (fmult(_state.a[1] >> 2, _state.sr[1]) +
		fmult(_state.a[0] >> 2, _state.sr[0]));
}

// computes the quantization step size of the adaptive quantizer.
int CADPCM::step_size()
{
	int		y;
	int		dif;
	int		al;

	if (_state.ap >= 256)
		return (_state.yu);
	else
	{
		y = _state.yl >> 6;
		dif = _state.yu - y;
		al = _state.ap >> 2;
		if (dif > 0)
			y += (dif * al) >> 6;
		else if (dif < 0)
			y += (dif * al + 0x3F) >> 6;
		return (y);
	}
}

// Given a raw sample, 'd', of the difference signal and a
// quantization step size scale factor, 'y', this routine returns the
// ADPCM codeword to which that sample gets quantized.  The step
// size scale factor division operation is done in the log base 2 domain
// as a subtraction.
int CADPCM::quantize(
					 int		d,		// Raw difference signal sample 
					 int		y,		// Step size multiplier 
					 short	*table,	// quantization table 
					 int		size)	// table size of short integers 
{
	short	dqm;	// Magnitude of 'd' 
	short	exp;	// Integer part of base 2 log of 'd' 
	short	mant;	// Fractional part of base 2 log 
	short	dl;		// Log of magnitude of 'd' 
	short	dln;	// Step size scale factor normalized log 
	int		i;

	//
	// LOG
	//
	// Compute base 2 log of 'd', and store in 'dl'.

	dqm = abs(d);
	exp = quan(dqm >> 1, (short*)POWER2, 15);
	mant = ((dqm << 7) >> exp) & 0x7F;	// Fractional portion. 
	dl = (exp << 7) + mant;

	//
	// SUBTB
	//
	// "Divide" by step size multiplier.

	dln = dl - (y >> 2);

	//
	// QUAN
	//
	// Obtain codword i for 'd'.

	i = quan(dln, table, size);
	if (d < 0)			// take 1's complement of i 
		return ((size << 1) + 1 - i);
	else if (i == 0)		// take 1's complement of 0 
		return ((size << 1) + 1); // new in 1988 
	else
		return (i);
}

//
// Returns reconstructed difference signal 'dq' obtained from
// codeword 'i' and quantization step size scale factor 'y'.
// Multiplication is performed in log base 2 domain as addition.
int CADPCM::reconstruct(
						int	sign,	// 0 for non-negative value 
						int	dqln,	// G.72x codeword 
						int	y)		// Step size multiplier 
{
	short	dql;	// Log of 'dq' magnitude 
	short	dex;	// Integer part of log 
	short	dqt;
	short	dq;		// Reconstructed difference signal sample 

	dql = dqln + (y >> 2);	// ADDA 

	if (dql < 0)
	{
		return ((sign) ? -0x8000 : 0);
	}
	else
	{		// ANTILOG 
		dex = (dql >> 7) & 15;
		dqt = 128 + (dql & 127);
		dq = (dqt << 7) >> (14 - dex);
		return ((sign) ? (dq - 0x8000) : dq);
	}
}

// updates the state variables for each output code
void CADPCM::update(
					int	code_size,	// distinguish 723_40 with others 
					int	y,			// quantizer step size 
					int	wi,			// scale factor multiplier 
					int	fi,			// for long/short term energies 
					int	dq,			// quantized prediction difference 
					int	sr,			// reconstructed signal 
					int	dqsez)		// difference from 2-pole predictor 
{
	int		cnt;
	short	mag, exp;	// Adaptive predictor, FLOAT A 
	short	a2p;		// LIMC 
	short	a1ul;		// UPA1 
	short	pks1;		// UPA2 
	short	fa1;
	char	tr;		// tone/transition detector 
	short	ylint, thr2, dqthr;
	short  	ylfrac, thr1;
	short	pk0;

	pk0 = (dqsez < 0) ? 1 : 0;	// needed in updating predictor poles 

	mag = dq & 0x7FFF;		// prediction difference magnitude 
	// TRANS 
	ylint = (short)(_state.yl >> 15);	// exponent part of yl 
	ylfrac = (short)((_state.yl >> 10) & 0x1F);	// fractional part of yl 
	thr1 = (32 + ylfrac) << ylint;			// threshold 
	thr2 = (ylint > 9) ? (short)(31 << 10) : thr1;	// limit thr2 to 31 << 10 
	dqthr = (thr2 + (thr2 >> 1)) >> 1;		// dqthr = 0.75 * thr2 

	if (_state.td == 0)		// signal supposed voice 
		tr = 0;
	else if (mag <= dqthr)		// supposed data, but small mag 
		tr = 0;			// treated as voice 
	else				// signal is data (modem) 
		tr = 1;

	// Quantizer scale factor adaptation.

	// FUNCTW & FILTD & DELAY 
	// update non-steady state step size multiplier 
	_state.yu = y + ((wi - y) >> 5);

	// LIMB 
	if (_state.yu < 544)	// 544 <= yu <= 5120 
		_state.yu = 544;
	else if (_state.yu > 5120)
		_state.yu = 5120;

	// FILTE & DELAY 
	// update steady state step size multiplier 
	_state.yl += _state.yu + ((-_state.yl) >> 6);

	// Adaptive predictor coefficients.

	if (tr == 1) // reset a's and b's for modem signal 
	{
		_state.a[0] = 0;
		_state.a[1] = 0;
		_state.b[0] = 0;
		_state.b[1] = 0;
		_state.b[2] = 0;
		_state.b[3] = 0;
		_state.b[4] = 0;
		_state.b[5] = 0;
	}
	else	// update a's and b's 
	{
		pks1 = pk0 ^ _state.pk[0];		// UPA2 

		// update predictor pole a[1] 
		a2p = _state.a[1] - (_state.a[1] >> 7);
		if (dqsez != 0)
		{
			fa1 = (pks1) ? _state.a[0] : -_state.a[0];
			if (fa1 < -8191)	// a2p = function of fa1 
				a2p -= 0x100;
			else if (fa1 > 8191)
				a2p += 0xFF;
			else
				a2p += fa1 >> 5;

			if (pk0 ^ _state.pk[1]) // LIMC
			{
				if (a2p <= -12160)
					a2p = -12288;
				else if (a2p >= 12416)
					a2p = 12288;
				else
					a2p -= 0x80;
			}
			else if (a2p <= -12416)
				a2p = -12288;
			else if (a2p >= 12160)
				a2p = 12288;
			else
				a2p += 0x80;
		}

		// TRIGB & DELAY 
		_state.a[1] = a2p;

		// UPA1 
		// update predictor pole a[0] 
		_state.a[0] -= _state.a[0] >> 8;
		if (dqsez != 0)
		{
			if (pks1 == 0)
				_state.a[0] += 192;
			else
				_state.a[0] -= 192;
		}

		// LIMD 
		a1ul = 15360 - a2p;
		if (_state.a[0] < -a1ul)
			_state.a[0] = -a1ul;
		else if (_state.a[0] > a1ul)
			_state.a[0] = a1ul;

		// UPB : update predictor zeros b[6] 
		for (cnt = 0; cnt < 6; cnt++)
		{
			if (code_size == 5)		// for 40Kbps G.723 
				_state.b[cnt] -= _state.b[cnt] >> 9;
			else					// for G.721 and 24Kbps G.723 
				_state.b[cnt] -= _state.b[cnt] >> 8;
			if (dq & 0x7FFF) // XOR 
			{
				if ((dq ^ _state.dq[cnt]) >= 0)
					_state.b[cnt] += 128;
				else
					_state.b[cnt] -= 128;
			}
		}
	}

	for (cnt = 5; cnt > 0; cnt--)
		_state.dq[cnt] = _state.dq[cnt-1];

	// FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. 
	if (mag == 0)
	{
		_state.dq[0] = (dq >= 0) ? 0x20 : 0xFC20;
	}
	else
	{
		exp = quan(mag, (short*)POWER2, 15);
		_state.dq[0] = (dq >= 0) ?
			(exp << 6) + ((mag << 6) >> exp) :
		(exp << 6) + ((mag << 6) >> exp) - 0x400;
	}

	_state.sr[1] = _state.sr[0];

	// FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. 
	if (sr == 0)
	{
		_state.sr[0] = 0x20;
	}
	else if (sr > 0)
	{
		exp = quan(sr, (short*)POWER2, 15);
		_state.sr[0] = (exp << 6) + ((sr << 6) >> exp);
	}
	else if (sr > -32768)
	{
		mag = -sr;
		exp = quan(mag, (short*)POWER2, 15);
		_state.sr[0] =  (exp << 6) + ((mag << 6) >> exp) - 0x400;
	}
	else
		_state.sr[0] = (short)0xFC20;

	// DELAY A 
	_state.pk[1] = _state.pk[0];
	_state.pk[0] = pk0;

	// TONE 
	if (tr == 1)			// this sample has been treated as data 
		_state.td = 0;	// next one will be treated as voice 
	else if (a2p < -11776)	// small sample-to-sample correlation 
		_state.td = 1;	// signal may be data 
	else					// signal is voice 
		_state.td = 0;

	// Adaptation speed control.

	_state.dms += (fi - _state.dms) >> 5;			// FILTA 
	_state.dml += (((fi << 2) - _state.dml) >> 7);	// FILTB 

	if (tr == 1)
		_state.ap = 256;
	else if (y < 1536)					// SUBTC
		_state.ap += (0x200 - _state.ap) >> 4;
	else if (_state.td == 1)
		_state.ap += (0x200 - _state.ap) >> 4;
	else if (abs((_state.dms << 2) - _state.dml) >= (_state.dml >> 3))
		_state.ap += (0x200 - _state.ap) >> 4;
	else
		_state.ap += (-_state.ap) >> 4;
}

// At the end of ADPCM decoding, it simulates an encoder which may be receiving
// the output of this decoder as a tandem process. If the output of the
// simulated encoder differs from the input to this decoder, the decoder output
// is adjusted by one level of A-law or u-law codes.
//
//Input:
//	sr	decoder output linear PCM sample,
//	se	predictor estimate sample,
//	y	quantizer step size,
//	i	decoder input code,
//	sign	sign bit of code i
//
// Return:
//	adjusted A-law or u-law compressed sample.
int CADPCM::tandem_adjust_alaw(
							   int		sr,	// decoder output linear PCM sample 
							   int		se,	// predictor estimate sample 
							   int		y,	// quantizer step size 
							   int		i,	// decoder input code 
							   int		sign,
							   short	*qtab)
{
	unsigned char	sp;		// A-law compressed 8-bit code 
	short			dx;		// prediction error 
	char			id;		// quantized prediction error 
	int				sd;		// adjusted A-law decoded sample value 
	int				im;		// biased magnitude of i 
	int				imx;	// biased magnitude of id 

	if (sr <= -32768)
		sr = -1;

	sp = linear2alaw((sr >> 1) << 3);	// short to A-law compression 
	dx = (alaw2linear(sp) >> 2) - se;	// 16-bit prediction error 
	id = quantize(dx, y, qtab, sign - 1);

	if (id == i)
	{	// no adjustment on sp 
		return (sp);
	}
	else  
	{	// sp adjustment needed
		// ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 
		im = i ^ sign;		// 2's complement to biased unsigned 
		imx = id ^ sign;

		if (imx > im)
		{	// sp adjusted to next lower value 
			if (sp & 0x80)
			{
				sd = (sp == 0xD5) ? 0x55 : ((sp ^ 0x55) - 1) ^ 0x55;
			}
			else
			{
				sd = (sp == 0x2A) ? 0x2A : ((sp ^ 0x55) + 1) ^ 0x55;
			}
		}
		else
		{	// sp adjusted to next higher value 
			if (sp & 0x80)
				sd = (sp == 0xAA) ? 0xAA : ((sp ^ 0x55) + 1) ^ 0x55;
			else
				sd = (sp == 0x55) ? 0xD5 : ((sp ^ 0x55) - 1) ^ 0x55;
		}
		return (sd);
	}
}

int CADPCM::tandem_adjust_ulaw(
							   int		sr,	// decoder output linear PCM sample 
							   int		se,	// predictor estimate sample 
							   int		y,	// quantizer step size 
							   int		i,	// decoder input code 
							   int		sign,
							   short	*qtab)
{
	unsigned char	sp;	// u-law compressed 8-bit code 
	short			dx;	// prediction error 
	char			id;	// quantized prediction error 
	int			sd;		// adjusted u-law decoded sample value 
	int			im;		// biased magnitude of i 
	int			imx;	// biased magnitude of id 

	if (sr <= -32768)
		sr = 0;
	sp = linear2ulaw(sr << 2);			// short to u-law compression 
	dx = (ulaw2linear(sp) >> 2) - se;	// 16-bit prediction error 
	id = quantize(dx, y, qtab, sign - 1);
	if (id == i)
	{
		return (sp);
	}
	else
	{
		// ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 
		im = i ^ sign;		// 2's complement to biased unsigned 
		imx = id ^ sign;
		if (imx > im)
		{	// sp adjusted to next lower value 
			if (sp & 0x80)
				sd = (sp == 0xFF) ? 0x7E : sp + 1;
			else
				sd = (sp == 0) ? 0 : sp - 1;

		}
		else
		{	// sp adjusted to next higher value 
			if (sp & 0x80)
				sd = (sp == 0x80) ? 0x80 : sp - 1;
			else
				sd = (sp == 0x7F) ? 0xFE : sp + 1;
		}
		return (sd);
	}
}

int CADPCM::search(int val, short *table, int size)
{
	int		i;

	for (i = 0; i < size; i++)
	{
		if (val <= *table++)
			return (i);
	}
	return (size);
}

// Convert a 16-bit linear PCM value to 8-bit A-law
// linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
//
//	Linear Input Code	Compressed Code
//	-----------------	---------------
//	0000000wxyza		000wxyz
//	0000001wxyza		001wxyz
//	000001wxyzab		010wxyz
//	00001wxyzabc		011wxyz
//	0001wxyzabcd		100wxyz
//	001wxyzabcde		101wxyz
//	01wxyzabcdef		110wxyz
//	1wxyzabcdefg		111wxyz
//
// For further information see John C. Bellamy's Digital Telephony, 1982,
// John Wiley & Sons, pps 98-111 and 472-476.
unsigned char CADPCM::linear2alaw(int pcm_val)	// 2's complement (16-bit range)
{
	int		mask;
	int		seg;
	unsigned char	aval;

	if (pcm_val >= 0)
	{
		mask = 0xD5;		// sign (7th) bit = 1
	}
	else
	{
		mask = 0x55;		// sign bit = 0
		pcm_val = -pcm_val - 8;
	}

	// Convert the scaled magnitude to segment number.
	seg = search(pcm_val, seg_end, 8);

	// Combine the sign, segment, and quantization bits.

	if (seg >= 8)		// out of range, return maximum value.
		return (0x7F ^ mask);
	else
	{
		aval = seg << SEG_SHIFT;
		if (seg < 2)
			aval |= (pcm_val >> 4) & QUANT_MASK;
		else
			aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;
		return (aval ^ mask);
	}
}

// alaw2linear() - Convert an A-law value to 16-bit linear PCM
int CADPCM::alaw2linear(unsigned char a_val)
{
	int		t;
	int		seg;

	a_val ^= 0x55;

	t = (a_val & QUANT_MASK) << 4;
	seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
	switch (seg)
	{
	case 0:
		t += 8;
		break;
	case 1:
		t += 0x108;
		break;
	default:
		t += 0x108;
		t <<= seg - 1;
	}
	return ((a_val & SIGN_BIT) ? t : -t);
}

// linear2ulaw() - Convert a linear PCM value to u-law
// In order to simplify the encoding process, the original linear magnitude
// is biased by adding 33 which shifts the encoding range from (0 - 8158) to
// (33 - 8191). The result can be seen in the following encoding table:
//
//	Biased Linear Input Code	Compressed Code
//	------------------------	---------------
//	00000001wxyza				000wxyz
//	0000001wxyzab				001wxyz
//	000001wxyzabc				010wxyz
//	00001wxyzabcd				011wxyz
//	0001wxyzabcde				100wxyz
//	001wxyzabcdef				101wxyz
//	01wxyzabcdefg				110wxyz
//	1wxyzabcdefgh				111wxyz
//
// Each biased linear code has a leading 1 which identifies the segment
// number. The value of the segment number is equal to 7 minus the number
// of leading 0's. The quantization interval is directly available as the
// four bits wxyz.  * The trailing bits (a - h) are ignored.
//  Ordinarily the complement of the resulting code word is used for
// transmission, and so the code word is complemented before it is returned.
//
// For further information see John C. Bellamy's Digital Telephony, 1982,
// John Wiley & Sons, pps 98-111 and 472-476.
unsigned char CADPCM::linear2ulaw(int pcm_val)	// 2's complement (16-bit range)
{
	int		mask;
	int		seg;
	unsigned char	uval;

	// Get the sign and the magnitude of the value.
	if (pcm_val < 0)
	{
		pcm_val = BIAS - pcm_val;
		mask = 0x7F;
	}
	else
	{
		pcm_val += BIAS;
		mask = 0xFF;
	}

	// Convert the scaled magnitude to segment number.
	seg = search(pcm_val, seg_end, 8);

	// Combine the sign, segment, quantization bits; and complement the code word.
	if (seg >= 8)	// out of range, return maximum value.
		return (0x7F ^ mask);
	else
	{
		uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);
		return (uval ^ mask);
	}
}

// ulaw2linear() - Convert a u-law value to 16-bit linear PCM
//
// First, a biased linear code is derived from the code word. An unbiased
// output can then be obtained by subtracting 33 from the biased code.
//
// Note that this function expects to be passed the complement of the
// original code word. This is in keeping with ISDN conventions.

int CADPCM::ulaw2linear(unsigned char u_val)
{
	int		t;

	// Complement to obtain normal u-law value.
	u_val = ~u_val;

	// Extract and bias the quantization bits. Then
	// shift up by the segment number and subtract out the bias.
	t = ((u_val & QUANT_MASK) << 3) + BIAS;
	t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;

	return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
}

// A-law to u-law conversion
unsigned char CADPCM::alaw2ulaw(unsigned char aval)
{
	aval &= 0xff;
	return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) : (0x7F ^ _a2u[aval ^ 0x55]));
}

// u-law to A-law conversion
unsigned char CADPCM::ulaw2alaw(unsigned char uval)
{
	uval &= 0xff;
	return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) : (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
}

//////////////////////////////////////////////////////////////////////
// CDecoder16
//////////////////////////////////////////////////////////////////////
// Maps G.723_16 code word to reconstructed scale factor normalized log magnitude values. Comes from Table 11/G.726
const short CDecoder16::_dqlntab[4] = { 116, 365, 365, 116}; 

// Maps G.723_16 code word to log of scale factor multiplier.
// _witab[4] is actually {-22 , 439, 439, -22}, but FILTD wants it
// as WI << 5  (multiplied by 32), so we'll do that here 
const short CDecoder16::_witab[4] = {-704, 14048, 14048, -704};

// Maps G.723_16 code words to a set of values whose long and short
// term averages are computed and then compared to give an indication
// how stationary (steady state) the signal is.

// Comes from FUNCTF
const short CDecoder16::_fitab[4] = {0, 0xE00, 0xE00, 0};

// Comes from quantizer decision level tables (Table 7/G.726)
const short CDecoder16::_qtab[1] = {261};

int CDecoder16::Run(int i)
{
	short sezi, sei, sez, se;	// ACCUM
	short y;					// MIX
	short sr;					// ADDB
	short dq;
	short dqsez;

	i &= 0x03;			// mask to get proper bits
	sezi = predictor_zero();
	sez = sezi >> 1;
	sei = sezi + predictor_pole();
	se = sei >> 1;		// se = estimated signal

	y = step_size();	// adaptive quantizer step size
	dq = reconstruct(i & 0x02, _dqlntab[i], y); // unquantize pred diff

	sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); // reconst. signal

	dqsez = sr - se + sez;	// pole prediction diff.

	update(2, y, _witab[i], _fitab[i], dq, sr, dqsez);

	switch (_coding_rule)
	{
	case CODING_ALAW:
		(tandem_adjust_alaw(sr, se, y, i, 2, (short*)_qtab));
		break;
	case CODING_ULAW:
		(tandem_adjust_ulaw(sr, se, y, i, 2, (short*)_qtab));
		break;
	case CODING_LINEAR:
		//sr << 2);	// sr was of 14-bit dynamic range
		break;
	default:
		return (-1);
	}

	return sr << 2;
}

//////////////////////////////////////////////////////////////////////
// CDecoder24
//////////////////////////////////////////////////////////////////////
// Maps G.723_24 code word to reconstructed scale factor normalized log magnitude values.
const short	CDecoder24::_dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048};

// Maps G.723_24 code word to log of scale factor multiplier.
const short	CDecoder24::_witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128};

// Maps G.723_24 code words to a set of values whose long and short
// term averages are computed and then compared to give an indication
// how stationary (steady state) the signal is.
const short	CDecoder24::_fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0};

const short CDecoder24::_qtab[3] = {8, 218, 331};

int CDecoder24::Run(int i)
{
	short sezi, sei, sez, se;	// ACCUM
	short y;					// MIX
	short sr;					// ADDB
	short dq;
	short dqsez;

	i &= 0x07;		// mask to get proper bits
	sezi = predictor_zero();
	sez = sezi >> 1;
	sei = sezi + predictor_pole();
	se = sei >> 1;	// se = estimated signal

	y = step_size();	// adaptive quantizer step size
	dq = reconstruct(i & 0x04, _dqlntab[i], y); // unquantize pred diff

	sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); // reconst. signal

	dqsez = sr - se + sez;	// pole prediction diff.

	update(3, y, _witab[i], _fitab[i], dq, sr, dqsez);

	switch (_coding_rule)
	{
	case CODING_ALAW:
		(tandem_adjust_alaw(sr, se, y, i, 4, (short*)_qtab));
		break;
	case CODING_ULAW:
		(tandem_adjust_ulaw(sr, se, y, i, 4, (short*)_qtab));
		break;
	case CODING_LINEAR:
		//return (sr << 2);	// sr was of 14-bit dynamic range
		break;
	default:
		return (-1);
	}

	return sr<<2;
}

//////////////////////////////////////////////////////////////////////
// CDecoder32
//////////////////////////////////////////////////////////////////////
// Maps G.721 code word to reconstructed scale factor normalized log magnitude values.
const short CDecoder32::_dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425, 425, 373, 323, 273, 213, 135, 4, -2048};

// Maps G.721 code word to log of scale factor multiplier.
const short CDecoder32::_witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122, 1122, 355, 198, 112, 64, 41, 18, -12};
// Maps G.721 code words to a set of values whose long and short
// term averages are computed and then compared to give an indication
// how stationary (steady state) the signal is.
const short CDecoder32::_fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0};

const short CDecoder32::_qtab[7] = {-124, 80, 178, 246, 300, 349, 400};

int CDecoder32::Run(int i)
{
	short sezi, sei, sez, se;	// ACCUM
	short y;					// MIX
	short sr;					// ADDB
	short dq;
	short dqsez;

	i &= 0x0f;		// mask to get proper bits 
	sezi = predictor_zero();
	sez = sezi >> 1;
	sei = sezi + predictor_pole();
	se = sei >> 1;	// se = estimated signal 

	y = step_size();	// dynamic quantizer step size 

	dq = reconstruct(i & 0x08, _dqlntab[i], y); // quantized diff. 

	sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq;	// reconst. signal 

	dqsez = sr - se + sez;			// pole prediction diff. 

	update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez);

	switch (_coding_rule)
	{
	case CODING_ALAW:
		(tandem_adjust_alaw(sr, se, y, i, 8, (short*)_qtab));
		break;
	case CODING_ULAW:
		(tandem_adjust_ulaw(sr, se, y, i, 8, (short*)_qtab));
		break;
	case CODING_LINEAR:
		//return (sr << 2);	// sr was 14-bit dynamic range 
		break;
	default:
		return (-1);
	}

	return sr<<2;
}

//////////////////////////////////////////////////////////////////////
// CDecoder40
//////////////////////////////////////////////////////////////////////
// Maps G.723_40 code word to ructeconstructed scale factor normalized log magnitude values.
const short CDecoder40::_dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318,
358, 395, 429, 459, 488, 514, 539, 566,
566, 539, 514, 488, 459, 429, 395, 358,
318, 274, 224, 169, 104, 28, -66, -2048};

// Maps G.723_40 code word to log of scale factor multiplier.
const short CDecoder40::_witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200,
4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272,
22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512,
3200, 1856, 1312, 1280, 1248, 768, 448, 448};

// Maps G.723_40 code words to a set of values whose long and short
// term averages are computed and then compared to give an indication
// how stationary (steady state) the signal is.
const short CDecoder40::_fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200,
0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00,
0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200,
0x200, 0x200, 0x200, 0, 0, 0, 0, 0};

const short CDecoder40::_qtab[15] = {-122, -16, 68, 139, 198, 250, 298, 339, 378, 413, 445, 475, 502, 528, 553};

int CDecoder40::Run(int i)
{
	short sezi, sei, sez, se;	// ACCUM 
	short y;					// MIX 
	short sr;					// ADDB 
	short dq;
	short dqsez;

	i &= 0x1f;			// mask to get proper bits 
	sezi = predictor_zero();
	sez = sezi >> 1;
	sei = sezi + predictor_pole();
	se = sei >> 1;		// se = estimated signal 

	y = step_size();	// adaptive quantizer step size 
	dq = reconstruct(i & 0x10, _dqlntab[i], y);	// estimation diff. 

	sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); // reconst. signal 

	dqsez = sr - se + sez;		// pole prediction diff. 

	update(5, y, _witab[i], _fitab[i], dq, sr, dqsez);

	switch (_coding_rule)
	{
	case CODING_ALAW:
		(tandem_adjust_alaw(sr, se, y, i, 0x10, (short*)_qtab));
		break;
	case CODING_ULAW:
		(tandem_adjust_ulaw(sr, se, y, i, 0x10, (short*)_qtab));
		break;
	case CODING_LINEAR:
		//return (sr << 2);	// sr was of 14-bit dynamic range 
		break;
	default:
		return (-1);
	}

	return sr<<2;
}

